using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Random = UnityEngine.Random;

namespace GameSystems
{
    /// <summary>
    /// 双因素认证系统 - 提供额外的安全层验证
    /// </summary>
    public class TwoFactorAuthSystem : MonoBehaviour
    {
        #region Events

        /// <summary>
        /// 验证码发送成功事件
        /// </summary>
        [Serializable] public class CodeSentEvent : UnityEvent<string> { }

        /// <summary>
        /// 双因素验证成功事件
        /// </summary>
        [Serializable] public class TwoFactorSuccessEvent : UnityEvent { }

        /// <summary>
        /// 双因素验证失败事件
        /// </summary>
        [Serializable] public class TwoFactorFailedEvent : UnityEvent<string> { }

        #endregion

        #region Serialized Fields

        [Header("双因素认证配置")]
        [Tooltip("是否启用双因素认证")]
        [SerializeField] private bool enableTwoFactorAuth = false;

        [Tooltip("验证码有效期（秒）")]
        [SerializeField] private int codeExpirationTime = 300;

        [Tooltip("验证码长度")]
        [SerializeField] private int codeLength = 6;

        [Tooltip("最大尝试次数")]
        [SerializeField] private int maxAttempts = 3;

        [Tooltip("重新发送冷却时间（秒）")]
        [SerializeField] private int resendCooldownTime = 60;

        [Header("验证方式")]
        [Tooltip("是否启用邮件验证")]
        [SerializeField] private bool enableEmailVerification = true;

        [Tooltip("是否启用短信验证")]
        [SerializeField] private bool enableSMSVerification = false;

        [Tooltip("是否启用应用验证器")]
        [SerializeField] private bool enableAppVerification = false;

        [Header("UI组件引用")]
        [Tooltip("验证码输入框")]
        [SerializeField] private InputField verificationCodeInputField;

        [Tooltip("验证按钮")]
        [SerializeField] private Button verifyButton;

        [Tooltip("重新发送按钮")]
        [SerializeField] private Button resendButton;

        [Tooltip("倒计时文本")]
        [SerializeField] private Text countdownText;

        [Tooltip("验证状态文本")]
        [SerializeField] private Text statusText;

        [Header("调试选项")]
        [Tooltip("是否启用调试日志")]
        [SerializeField] private bool enableDebugLogs = true;

        [Tooltip("测试模式验证码")]
        [SerializeField] private string testVerificationCode = "123456";

        #endregion

        #region Events

        [Header("事件回调")]
        [Tooltip("验证码发送成功时触发")]
        public CodeSentEvent OnCodeSent;

        [Tooltip("双因素验证成功时触发")]
        public TwoFactorSuccessEvent OnTwoFactorSuccess;

        [Tooltip("双因素验证失败时触发")]
        public TwoFactorFailedEvent OnTwoFactorFailed;

        #endregion

        #region Private Fields

        private string currentVerificationCode;
        private DateTime codeGeneratedTime;
        private int currentAttempts = 0;
        private bool isCooldownActive = false;
        private Coroutine cooldownCoroutine;
        private Coroutine expirationCoroutine;

        // 验证方式枚举
        public enum VerificationMethod
        {
            Email,
            SMS,
            App
        }

        private VerificationMethod currentMethod = VerificationMethod.Email;

        #endregion

        #region Unity Lifecycle

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void Awake()
        {
            InitializeUI();
            ValidateComponents();
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        private void OnDestroy()
        {
            CleanupCoroutines();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 开始双因素认证流程
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="method">验证方式</param>
        public void StartTwoFactorAuth(string username, VerificationMethod method = VerificationMethod.Email)
        {
            if (!enableTwoFactorAuth)
            {
                LogDebug("双因素认证未启用，跳过验证");
                OnTwoFactorSuccess?.Invoke();
                return;
            }

            currentMethod = method;
            GenerateVerificationCode();
            SendVerificationCode(username);
            StartExpirationTimer();
            ResetAttempts();

            ShowVerificationUI(true);
            UpdateStatusText($"验证码已发送到{GetMethodInfo(method)}");
            OnCodeSent?.Invoke(GetMethodInfo(method));
        }

        /// <summary>
        /// 验证输入的验证码
        /// </summary>
        /// <param name="inputCode">用户输入的验证码</param>
        public void VerifyCode(string inputCode)
        {
            if (string.IsNullOrEmpty(inputCode))
            {
                ShowError("请输入验证码");
                return;
            }

            if (currentAttempts >= maxAttempts)
            {
                ShowError("验证尝试次数过多，请重新开始");
                OnTwoFactorFailed?.Invoke("验证尝试次数过多");
                return;
            }

            if (IsCodeExpired())
            {
                ShowError("验证码已过期，请重新获取");
                OnTwoFactorFailed?.Invoke("验证码已过期");
                return;
            }

            currentAttempts++;

            if (inputCode == currentVerificationCode || (enableDebugLogs && inputCode == testVerificationCode))
            {
                OnVerificationSuccess();
            }
            else
            {
                ShowError($"验证码错误，还有{maxAttempts - currentAttempts}次机会");
                if (currentAttempts >= maxAttempts)
                {
                    OnTwoFactorFailed?.Invoke("验证码错误次数过多");
                }
            }
        }

        /// <summary>
        /// 重新发送验证码
        /// </summary>
        /// <param name="username">用户名</param>
        public void ResendCode(string username)
        {
            if (isCooldownActive)
            {
                ShowError($"请等待{resendCooldownTime}秒后重新发送");
                return;
            }

            GenerateVerificationCode();
            SendVerificationCode(username);
            StartExpirationTimer();
            StartResendCooldown();

            UpdateStatusText($"验证码已重新发送到{GetMethodInfo(currentMethod)}");
            OnCodeSent?.Invoke(GetMethodInfo(currentMethod));
        }

        /// <summary>
        /// 取消双因素认证
        /// </summary>
        public void CancelTwoFactorAuth()
        {
            CleanupCoroutines();
            ShowVerificationUI(false);
            ResetAttempts();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 生成验证码
        /// </summary>
        private void GenerateVerificationCode()
        {
            currentVerificationCode = "";
            for (int i = 0; i < codeLength; i++)
            {
                currentVerificationCode += Random.Range(0, 10).ToString();
            }
            codeGeneratedTime = DateTime.Now;

            LogDebug($"生成验证码: {currentVerificationCode} (测试模式)");
        }

        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="username">用户名</param>
        private void SendVerificationCode(string username)
        {
            // 实际项目中，这里应该调用邮件/短信服务API
            StartCoroutine(SendVerificationCodeCoroutine(username));
        }

        /// <summary>
        /// 发送验证码协程
        /// </summary>
        private IEnumerator SendVerificationCodeCoroutine(string username)
        {
            LogDebug($"正在发送验证码到{GetMethodInfo(currentMethod)}");

            // 模拟网络请求延迟
            yield return new WaitForSeconds(1f);

            // 实际项目中，这里应该调用相应的API
            switch (currentMethod)
            {
                case VerificationMethod.Email:
                    // 调用邮件服务API
                    LogDebug($"邮件验证码已发送到 {username}@example.com");
                    break;
                case VerificationMethod.SMS:
                    // 调用短信服务API
                    LogDebug($"短信验证码已发送到 {username}的手机号");
                    break;
                case VerificationMethod.App:
                    // 生成应用验证器代码
                    LogDebug($"应用验证器代码已生成");
                    break;
            }
        }

        /// <summary>
        /// 启动过期计时器
        /// </summary>
        private void StartExpirationTimer()
        {
            if (expirationCoroutine != null)
            {
                StopCoroutine(expirationCoroutine);
            }
            expirationCoroutine = StartCoroutine(ExpirationTimerCoroutine());
        }

        /// <summary>
        /// 过期计时器协程
        /// </summary>
        private IEnumerator ExpirationTimerCoroutine()
        {
            yield return new WaitForSeconds(codeExpirationTime);

            if (currentVerificationCode != null)
            {
                ShowError("验证码已过期");
                OnTwoFactorFailed?.Invoke("验证码已过期");
            }
        }

        /// <summary>
        /// 检查验证码是否过期
        /// </summary>
        private bool IsCodeExpired()
        {
            return (DateTime.Now - codeGeneratedTime).TotalSeconds > codeExpirationTime;
        }

        /// <summary>
        /// 启动重新发送冷却
        /// </summary>
        private void StartResendCooldown()
        {
            if (cooldownCoroutine != null)
            {
                StopCoroutine(cooldownCoroutine);
            }
            cooldownCoroutine = StartCoroutine(ResendCooldownCoroutine());
        }

        /// <summary>
        /// 重新发送冷却协程
        /// </summary>
        private IEnumerator ResendCooldownCoroutine()
        {
            isCooldownActive = true;
            int remainingTime = resendCooldownTime;

            while (remainingTime > 0)
            {
                UpdateCountdownText($"重新发送 ({remainingTime}s)");
                yield return new WaitForSeconds(1f);
                remainingTime--;
            }

            isCooldownActive = false;
            UpdateCountdownText("重新发送");
        }

        /// <summary>
        /// 验证成功处理
        /// </summary>
        private void OnVerificationSuccess()
        {
            LogDebug("双因素认证成功");
            ShowVerificationUI(false);
            UpdateStatusText("验证成功");
            OnTwoFactorSuccess?.Invoke();
        }

        /// <summary>
        /// 重置尝试次数
        /// </summary>
        private void ResetAttempts()
        {
            currentAttempts = 0;
        }

        /// <summary>
        /// 获取验证方式信息
        /// </summary>
        private string GetMethodInfo(VerificationMethod method)
        {
            switch (method)
            {
                case VerificationMethod.Email:
                    return "邮箱";
                case VerificationMethod.SMS:
                    return "手机";
                case VerificationMethod.App:
                    return "验证器应用";
                default:
                    return "未知方式";
            }
        }

        /// <summary>
        /// 显示/隐藏验证UI
        /// </summary>
        private void ShowVerificationUI(bool show)
        {
            if (verificationCodeInputField != null)
                verificationCodeInputField.gameObject.SetActive(show);
            if (verifyButton != null)
                verifyButton.gameObject.SetActive(show);
            if (resendButton != null)
                resendButton.gameObject.SetActive(show);
            if (countdownText != null)
                countdownText.gameObject.SetActive(show);
        }

        /// <summary>
        /// 更新状态文本
        /// </summary>
        private void UpdateStatusText(string message)
        {
            if (statusText != null)
                statusText.text = message;
        }

        /// <summary>
        /// 更新倒计时文本
        /// </summary>
        private void UpdateCountdownText(string text)
        {
            if (countdownText != null)
                countdownText.text = text;
        }

        /// <summary>
        /// 显示错误信息
        /// </summary>
        private void ShowError(string message)
        {
            LogError(message);
            UpdateStatusText($"<color=red>{message}</color>");
        }

        /// <summary>
        /// 初始化UI
        /// </summary>
        private void InitializeUI()
        {
            if (verifyButton != null)
                verifyButton.onClick.AddListener(() => VerifyCode(verificationCodeInputField?.text ?? ""));

            if (resendButton != null)
                resendButton.onClick.AddListener(() => ResendCode("")); // 需要传入实际用户名

            ShowVerificationUI(false);
        }

        /// <summary>
        /// 验证组件
        /// </summary>
        private void ValidateComponents()
        {
            if (enableTwoFactorAuth)
            {
                if (verificationCodeInputField == null)
                    LogWarning("验证码输入框未设置");
                if (verifyButton == null)
                    LogWarning("验证按钮未设置");
                if (resendButton == null)
                    LogWarning("重新发送按钮未设置");
            }
        }

        /// <summary>
        /// 清理协程
        /// </summary>
        private void CleanupCoroutines()
        {
            if (cooldownCoroutine != null)
            {
                StopCoroutine(cooldownCoroutine);
                cooldownCoroutine = null;
            }

            if (expirationCoroutine != null)
            {
                StopCoroutine(expirationCoroutine);
                expirationCoroutine = null;
            }
        }

        #endregion

        #region Debug Methods

        /// <summary>
        /// 调试日志
        /// </summary>
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
                Debug.Log($"[TwoFactorAuthSystem] {message}");
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        private void LogWarning(string message)
        {
            if (enableDebugLogs)
                Debug.LogWarning($"[TwoFactorAuthSystem] {message}");
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        private void LogError(string message)
        {
            if (enableDebugLogs)
                Debug.LogError($"[TwoFactorAuthSystem] {message}");
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// 是否启用双因素认证
        /// </summary>
        public bool EnableTwoFactorAuth
        {
            get => enableTwoFactorAuth;
            set => enableTwoFactorAuth = value;
        }

        /// <summary>
        /// 是否在冷却中
        /// </summary>
        public bool IsCooldownActive => isCooldownActive;

        /// <summary>
        /// 当前验证方式
        /// </summary>
        public VerificationMethod CurrentMethod => currentMethod;

        #endregion
    }
}
